/*
 * Copyright 2010 Biz-e (info@biz-e.nl)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.biz_e.site.client.editor;

import java.util.HashMap;
import java.util.List;

import nl.biz_e.gwt.baselib.ui.client.widgets.GroupBox;
import nl.biz_e.site.shared.models.Version;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Enables version selection and editting
 * 
 * @author Joost A. Bloemsma
 */
public class ContentSelector extends Composite {
	
	class EventHandler implements ChangeHandler, ClickHandler {
		private final ContentSelector selector;
		
		EventHandler(ContentSelector selector) {
			this.selector = selector;
		}
		
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onChange(ChangeEvent change) {
			if (change.getSource() == selector.keyList) {
				selector.keyChanged(keyList
						.getValue(keyList.getSelectedIndex()));
			}
			
			if (change.getSource() == selector.versionList) {
				selector.versionChanged();
			}
		}
		
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onClick(ClickEvent click) {
			if (click.getSource() == selectButton) {
				selector.doSelect();
			} else if (click.getSource() == activateButton) {
				selector.setActive();
			} else if (click.getSource() == saveButton) {
				selector.doSave();
			}
			
		}
	}
	
	private ListBox keyList;
	private ListBox versionList;
	private Button selectButton;
	private Button activateButton;
	private Button saveButton;
	private Label activeLabel;
	private final EditorPanel mainPanel;
	private final EditorStrings strings;
	private final EventHandler event;
	private HashMap<String, Version> versions = new HashMap<String, Version>();
	
	/**
	 * Constructs a new ContentSelector instance
	 * 
	 * @param mainPanel
	 */
	public ContentSelector(EditorPanel mainPanel) {
		super();
		event = new EventHandler(this);
		this.mainPanel = mainPanel;
		strings = (EditorStrings) GWT.create(EditorStrings.class);
		this.init();
	}
	
	private void init() {
		GroupBox gb = new GroupBox();
		gb.setCaption(strings.selectContentVersion());
		
		VerticalPanel vp = new VerticalPanel();
		Grid grid = new Grid(1, 5);
		grid.setWidget(0, 0, new Label(strings.key()));
		grid.setWidget(0, 1, getKeyList());
		grid.setWidget(0, 2, new Label(strings.version()));
		grid.setWidget(0, 3, getVersionList());
		activeLabel = new Label(strings.active());
		activeLabel.setVisible(false);
		grid.setWidget(0, 4, activeLabel);
		vp.add(grid);
		selectButton = new Button(strings.select(), this.event);
		activateButton = new Button(strings.activate(), this.event);
		saveButton = new Button(strings.save(), this.event);
		HorizontalPanel hp2 = new HorizontalPanel();
		hp2.add(selectButton);
		hp2.add(activateButton);
		hp2.add(saveButton);
		vp.add(hp2);
		
		gb.add(vp);
		
		this.initWidget(gb);
		
	}
	
	private ListBox getKeyList() {
		if (keyList == null) {
			keyList = new ListBox(false);
			keyList.addItem(strings.select(), "");
			mainPanel.getService().getAvailableKeys(
					new AsyncCallback<List<String>>() {
						@Override
						public void onSuccess(List<String> result) {
							for (String key : result) {
								keyList.addItem(key);
							}
						}
						
						@Override
						public void onFailure(Throwable caught) {
							mainPanel.getAppManager().showMessage(
									mainPanel.getAppManager().getMessages()
											.serverError());
						}
					});
			keyList.addChangeHandler(event);
		}
		return keyList;
	}
	
	private ListBox getVersionList() {
		if (versionList == null) {
			versionList = new ListBox();
			versionList.addItem(strings.select());
			versionList.addChangeHandler(event);
		}
		return versionList;
	}
	
	void doSelect() {
		mainPanel.versionSelected(getSelectedVersion());
	}
	
	void doSave() {
		mainPanel.saveNewContent(getSelectedVersion());
	}
	
	void setActive() {
		final Version v = getSelectedVersion();
		mainPanel.getService().setActiveVersion(v,
				new AsyncCallback<Version>() {
					
					@Override
					public void onFailure(Throwable caught) {
						mainPanel.getAppManager().showMessage(
								mainPanel.getAppManager().getMessages()
										.serverError());
					}
					
					@Override
					public void onSuccess(Version result) {
						for (Version vers : versions.values()) {
							vers.setActive(vers == v);
						}
						checkSelectedVersion();
						String msg = strings.activated();
						if (result != null) {
							msg += "\n" + result.getVersion().toString() + " "
									+ strings.deactivated();
						}
						mainPanel.getAppManager().showMessage(msg);
					}
				});
	}
	
	private Version getSelectedVersion() {
		String v = versionList.getValue(versionList.getSelectedIndex());
		Version version = versions.get(v);
		if (version == null) {
			version = new Version();
			version.setKey(keyList.getValue(keyList.getSelectedIndex()));
			version.setVersion(0);
		}
		return version;
	}
	
	void versionChanged() {
		checkSelectedVersion();
	}
	
	private void checkSelectedVersion() {
		String v = versionList.getValue(versionList.getSelectedIndex());
		Version version = versions.get(v);
		activeLabel.setVisible(version.isActive());
	}
	
	void keyChanged(String newKey) {
		versionList.clear();
		versions.clear();
		versionList.addItem(strings.select());
		mainPanel.getService().getAvailableVersions(newKey,
				new AsyncCallback<List<Version>>() {
					@Override
					public void onSuccess(List<Version> result) {
						Version activeVersion = null;
						for (Version v : result) {
							versionList.addItem(v.getVersion().toString());
							versions.put(v.getVersion().toString(), v);
							if (v.isActive()) {
								activeVersion = v;
							}
						}
						if (activeVersion != null) {
							selectVersion(activeVersion);
						}
					}
					
					@Override
					public void onFailure(Throwable caught) {
						mainPanel.getAppManager().showMessage(
								mainPanel.getAppManager().getMessages()
										.serverError());
					}
				});
	}
	
	void selectVersion(Version v) {
		String versNr = v.getVersion().toString();
		if (!versions.containsKey(versNr)) {
			versionList.addItem(versNr);
		}
		versions.put(versNr, v);
		for (int i = 0; i < versionList.getItemCount(); i++) {
			if (versionList.getItemText(i).equals(versNr)) {
				selectVersion(i);
				return;
			}
		}
		selectVersion(0);
	}
	
	void selectVersion(int v) {
		versionList.setSelectedIndex(v);
		checkSelectedVersion();
	}
}
